﻿using System.Linq;
using System.Management;
using System.Reflection;
using System.Collections.Generic;

namespace ClusterAwareProperties
{
    /// <summary>
    /// Extend class for Enum operations with ManagementObject
    /// </summary>
    public static class EnumExtender
    {
        /// <summary>
        /// Get property value from ManagementObject and convert T type
        /// </summary>
        /// <typeparam name="T">Type to converter</typeparam>
        /// <param name="queryObj">ManagementObject</param>
        /// <param name="nameProperty">name property</param>
        /// <returns>Type T</returns>
        public static T PropertyValue<T>(this ManagementBaseObject queryObj, string nameProperty)
        {
            try
            {
                return (T)queryObj[nameProperty];

            }
            catch
            {
                return default(T);
            }

        }

        /// <summary>
        /// Get property value from ManagementObject and convert to TU type enumerator
        /// </summary>
        /// <typeparam name="T">property Type ManagementObject</typeparam>
        /// <typeparam name="TU">Enumerator type to converter</typeparam>
        /// <param name="queryObj">ManagementObject</param>
        /// <param name="namePropertye">Name property</param>
        /// <param name="defaultvalue">TU Default value</param>
        /// <returns>enumerator TU</returns>
        public static TU PropertyEnum<T, TU>(this ManagementBaseObject queryObj, string namePropertye,TU defaultvalue)
        {
            var result = defaultvalue;
            try
            {
                var value = (T)queryObj[namePropertye];
                if (typeof(T).Equals(typeof(string)))
                {
                    foreach (var field in
                        typeof(TU).GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public).Where(field => value.ToString() == field.GetValue(null).ToString()))
                    {
                        result = (TU)field.GetValue(null);
                        break;
                    }
                }
                else
                {
                    foreach (var field in
                        typeof(TU).GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public).Where(field => value.ToString() == ((int)field.GetValue(null)).ToString()))
                    {
                        result = (TU)field.GetValue(null);
                        break;
                    }
                }
                return result;
            }
            catch
            {
                return result;
            }
        }

        /// <summary>
        /// Get property value from ManagementObject and convert to array TU type enumerator
        /// </summary>
        /// <typeparam name="T">property Type ManagementObject</typeparam>
        /// <typeparam name="TU">Enumerator type to converter</typeparam>
        /// <param name="queryObj">ManagementObject</param>
        /// <param name="namePropertye">Name property</param>
        /// <returns>Array enumetator TU </returns>
        public static TU[] PropertyArrayEnum<T, TU>(this ManagementObject queryObj, string namePropertye)
        {

            var result = new List<TU>();
            try
            {
                var value = (IEnumerable<T>)queryObj[namePropertye];
                foreach (var item in value)
                {
                    foreach (var field in
                            // ReSharper disable AccessToModifiedClosure
                            typeof(TU).GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public).Where(field => item.ToString() == ((int)field.GetValue(null)).ToString()))
                            // ReSharper restore AccessToModifiedClosure
                    {
                        result.Add((TU)field.GetValue(null));
                        break;
                    }

                }
                return result.ToArray();
            }
            catch
            {
                return null;
            }
        }

    }
}
